﻿namespace Microsoft.SharePoint.Client
{
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Runtime.CompilerServices;

    public static class ClientObjectQueryableExtension
    {
        internal const string IncludeMethodName = "Include";
        internal const string IncludeWithDefaultPropertiesName = "IncludeWithDefaultProperties";

        public static IQueryable<TSource> Include<TSource>(this IQueryable<TSource> clientObjects, params Expression<Func<TSource, object>>[] retrievals) where TSource: ClientObject
        {
            if (clientObjects == null)
            {
                throw new ArgumentNullException("clientObjects");
            }
            if (retrievals == null)
            {
                throw new ArgumentNullException("retrievals");
            }
            NewArrayExpression expression = Expression.NewArrayInit(typeof(Expression<Func<TSource, object>>), (Expression[]) retrievals);
            return clientObjects.Provider.CreateQuery<TSource>(Expression.Call(null, ((MethodInfo) MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource) }), new Expression[] { clientObjects.Expression, expression }));
        }

        public static IQueryable<TSource> IncludeWithDefaultProperties<TSource>(this IQueryable<TSource> clientObjects, params Expression<Func<TSource, object>>[] retrievals) where TSource: ClientObject
        {
            if (clientObjects == null)
            {
                throw new ArgumentNullException("clientObjects");
            }
            if (retrievals == null)
            {
                throw new ArgumentNullException("retrievals");
            }
            NewArrayExpression expression = Expression.NewArrayInit(typeof(Expression<Func<TSource, object>>), (Expression[]) retrievals);
            return clientObjects.Provider.CreateQuery<TSource>(Expression.Call(null, ((MethodInfo) MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource) }), new Expression[] { clientObjects.Expression, expression }));
        }
    }
}

